dofile (getScriptPath() .. "\\..\\processor\\processor.lua")
dofile (getScriptPath() .. "\\..\\processor\\log.lua")

dofile (getScriptPath() .. "\\..\\lib\\lib.lua")
dofile (getScriptPath() .. "\\..\\lib\\orders.lua")
dofile (getScriptPath() .. "\\..\\lib\\actions.lua")

script_name = string.gsub(string.gsub(debug.getinfo(1).short_src, "%.[^%.]*$", ""), "^.*[\\/]", "")

data = {
	codes = {},
	delay = 2,
}

processor:AddInit(function()
	if not lib:isConnected() then return true end
	client_code = lib:GetUser()
	script_id = client_code .. "#" .. script_name
	processor:InitLog(lib.path.log .. script_id .. ".log")
	processor:log("started")
end)

	
processor:AddTimer(function()
	if orders:InProcess() then
		return true
	end

end)

	
processor:AddTimer(function()
	local codes = {}
	
	for _, order in ipairs(orders:GetActiveStops(nil, "sec_code")) do
		if codes[order.sec_code] then
			codes[order.sec_code].pos = codes[order.sec_code].pos + order.balance
			codes[order.sec_code].n = codes[order.sec_code].n + 1
		else
			codes[order.sec_code] = {order = order, pos = order.balance, n = 1, delay = data.delay}
		end
	end
	
	for code, d in pairs(codes) do
		if d.n > 1 and not data.codes[code] then
			data.codes[code] = d
		elseif d.n == 1 and data.codes[code] then
			for _, _ in pairs(orders:GetLimits(code)) do
				d = nil
				break
			end
			
			if d then
				if data.codes[code].delay > 0 then
					data.codes[code].delay = data.codes[code].delay - 1
						
					message("delay=" .. tostring(data.codes[code].delay))
				else
					message(lib:toline(d))
										
					local instrument = lib:GetInstrument(code)
					
					if instrument then
						local is_long = orders:IsPositionLong(d.order)
						local tev = orders:GetLastTradePrice(instrument, not is_long)
						local sl = orders:GetStopPrice(d.order)
						
						message("sl=" .. tostring(sl) .. " tev=" .. tostring(tev) .. " is_long=" .. tostring(is_long))
						
						if is_long ~= nil and sl and tev then
							local do_exit = false
							local lm, side, trade = orders:GetLastTradePrice(instrument, is_long)
						
							message("lm=" .. tostring(lm) .. " trade=" .. lib:toline(trade))
							
							if lm and trade then
								local tm = trade.datetime
								tm.sec = 0
								tm = lib:tickseconds() - lib:tickseconds(tm)
								
								if tm >= 0 then
									tm = int(tm / 60) + 2
						
									message("tm=" .. tostring(tm) .. " min")
								
									local ds, err = lib:CreateDataSource(instrument)
									
									if ds then
										local low, high = lib:GetCandleRange(ds, 0, tm)
										local pivot_stop = lm
										
										if is_long then
											if low and lm > low then
												do_exit = (3 * sl + lm) / 4 > low
												pivot_stop = low - instrument.min_price_step
											end
										else
											if high and lm < high then
												do_exit = (3 * sl + lm) / 4 < high
												pivot_stop = high + instrument.min_price_step
											end
										end
										
										ds:Close()
										
										if lm ~= pivot_stop then
											message("pivot stop " .. tostring(pivot_stop) .. " do_exit " .. tostring(do_exit))
											
											lm = pivot_stop
										end
									else
										fail("DataSource error: " .. tostring(err))
									end
								end
							end
							
							--if do_exit then
							--	actions:Exit(instrument)
							--else
								if is_long == (tev > sl) then
									orders:ShiftEven(code,
										sl,
										tev,
										data.codes[code].pos,
										data.codes[code].pos - d.order.balance,
										lm		-- may be nil
									)
								else
									fail("wrong params")
								end
							--end
						else
							data.codes[code].delay = data.delay
						end
					else
						fail("instrument not found: " .. code)
					end
					
					data.codes[code] = nil
				end
			else
				data.codes[code].delay = data.delay
			end
		end
	end
	
	for code, n in pairs(data.codes) do
		if not codes[code] then
			data.codes[code] = nil
		end
	end
end)

